home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / jpegsrc4.zip / JCMAIN.C < prev    next >
C/C++ Source or Header  |  1992-12-04  |  21KB  |  693 lines

  1. /*
  2.  * jcmain.c
  3.  *
  4.  * Copyright (C) 1991, 1992, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains a command-line user interface for the JPEG compressor.
  9.  * It should work on any system with Unix- or MS-DOS-style command lines.
  10.  *
  11.  * Two different command line styles are permitted, depending on the
  12.  * compile-time switch TWO_FILE_COMMANDLINE:
  13.  *    cjpeg [options]  inputfile outputfile
  14.  *    cjpeg [options]  [inputfile]
  15.  * In the second style, output is always to standard output, which you'd
  16.  * normally redirect to a file or pipe to some other program.  Input is
  17.  * either from a named file or from standard input (typically redirected).
  18.  * The second style is convenient on Unix but is unhelpful on systems that
  19.  * don't support pipes.  Also, you MUST use the first style if your system
  20.  * doesn't do binary I/O to stdin/stdout.
  21.  */
  22.  
  23. #include "jinclude.h"
  24. #ifdef INCLUDES_ARE_ANSI
  25. #include <stdlib.h>        /* to declare exit() */
  26. #endif
  27. #include <ctype.h>        /* to declare isupper(), tolower() */
  28. #ifdef NEED_SIGNAL_CATCHER
  29. #include <signal.h>        /* to declare signal() */
  30. #endif
  31. #ifdef USE_SETMODE
  32. #include <fcntl.h>        /* to declare setmode() */
  33. #endif
  34.  
  35. #ifdef THINK_C
  36. #include <console.h>        /* command-line reader for Macintosh */
  37. #endif
  38.  
  39. #ifdef DONT_USE_B_MODE        /* define mode parameters for fopen() */
  40. #define READ_BINARY    "r"
  41. #define WRITE_BINARY    "w"
  42. #else
  43. #define READ_BINARY    "rb"
  44. #define WRITE_BINARY    "wb"
  45. #endif
  46.  
  47. #ifndef EXIT_FAILURE        /* define exit() codes if not provided */
  48. #define EXIT_FAILURE  1
  49. #endif
  50. #ifndef EXIT_SUCCESS
  51. #ifdef VMS
  52. #define EXIT_SUCCESS  1        /* VMS is very nonstandard */
  53. #else
  54. #define EXIT_SUCCESS  0
  55. #endif
  56. #endif
  57.  
  58.  
  59. #include "jversion.h"        /* for version message */
  60.  
  61.  
  62. /*
  63.  * This routine determines what format the input file is,
  64.  * and selects the appropriate input-reading module.
  65.  *
  66.  * To determine which family of input formats the file belongs to,
  67.  * we may look only at the first byte of the file, since C does not
  68.  * guarantee that more than one character can be pushed back with ungetc.
  69.  * Looking at additional bytes would require one of these approaches:
  70.  *     1) assume we can fseek() the input file (fails for piped input);
  71.  *     2) assume we can push back more than one character (works in
  72.  *        some C implementations, but unportable);
  73.  *     3) provide our own buffering as is done in djpeg (breaks input readers
  74.  *        that want to use stdio directly, such as the RLE library);
  75.  * or  4) don't put back the data, and modify the input_init methods to assume
  76.  *        they start reading after the start of file (also breaks RLE library).
  77.  * #1 is attractive for MS-DOS but is untenable on Unix.
  78.  *
  79.  * The most portable solution for file types that can't be identified by their
  80.  * first byte is to make the user tell us what they are.  This is also the
  81.  * only approach for "raw" file types that contain only arbitrary values.
  82.  * We presently apply this method for Targa files.  Most of the time Targa
  83.  * files start with 0x00, so we recognize that case.  Potentially, however,
  84.  * a Targa file could start with any byte value (byte 0 is the length of the
  85.  * seldom-used ID field), so we provide a switch to force Targa input mode.
  86.  */
  87.  
  88. static boolean is_targa;    /* records user -targa switch */
  89.  
  90.  
  91. LOCAL void
  92. select_file_type (compress_info_ptr cinfo)
  93. {
  94.   int c;
  95.  
  96.   if (is_targa) {
  97. #ifdef TARGA_SUPPORTED
  98.     jselrtarga(cinfo);
  99. #else
  100.     ERREXIT(cinfo->emethods, "Targa support was not compiled");
  101. #endif
  102.     return;
  103.   }
  104.  
  105.   if ((c = getc(cinfo->input_file)) == EOF)
  106.     ERREXIT(cinfo->emethods, "Empty input file");
  107.  
  108.   switch (c) {
  109. #ifdef GIF_SUPPORTED
  110.   case 'G':
  111.     jselrgif(cinfo);
  112.     break;
  113. #endif
  114. #ifdef PPM_SUPPORTED
  115.   case 'P':
  116.     jselrppm(cinfo);
  117.     break;
  118. #endif
  119. #ifdef RLE_SUPPORTED
  120.   case 'R':
  121.     jselrrle(cinfo);
  122.     break;
  123. #endif
  124. #ifdef TARGA_SUPPORTED
  125.   case 0x00:
  126.     jselrtarga(cinfo);
  127.     break;
  128. #endif
  129.   default:
  130. #ifdef TARGA_SUPPORTED
  131.     ERREXIT(cinfo->emethods, "Unrecognized input file format --- perhaps you need -targa");
  132. #else
  133.     ERREXIT(cinfo->emethods, "Unrecognized input file format");
  134. #endif
  135.     break;
  136.   }
  137.  
  138.   if (ungetc(c, cinfo->input_file) == EOF)
  139.     ERREXIT(cinfo->emethods, "ungetc failed");
  140. }
  141.  
  142.  
  143. /*
  144.  * This routine gets control after the input file header has been read.
  145.  * It must determine what output JPEG file format is to be written,
  146.  * and make any other compression parameter changes that are desirable.
  147.  */
  148.  
  149. METHODDEF void
  150. c_ui_method_selection (compress_info_ptr cinfo)
  151. {
  152.   /* If the input is gray scale, generate a monochrome JPEG file. */
  153.   if (cinfo->in_color_space == CS_GRAYSCALE)
  154.     j_monochrome_default(cinfo);
  155.   /* For now, always select JFIF output format. */
  156. #ifdef JFIF_SUPPORTED
  157.   jselwjfif(cinfo);
  158. #else
  159.   You shoulda defined JFIF_SUPPORTED.   /* deliberate syntax error */
  160. #endif
  161. }
  162.  
  163.  
  164. /*
  165.  * Signal catcher to ensure that temporary files are removed before aborting.
  166.  * NB: for Amiga Manx C this is actually a global routine named _abort();
  167.  * see -Dsignal_catcher=_abort in CFLAGS.  Talk about bogus...
  168.  */
  169.  
  170. #ifdef NEED_SIGNAL_CATCHER
  171.  
  172. static external_methods_ptr emethods; /* for access to free_all */
  173.  
  174. GLOBAL void
  175. signal_catcher (int signum)
  176. {
  177.   if (emethods != NULL) {
  178.     emethods->trace_level = 0;    /* turn off trace output */
  179.     (*emethods->free_all) ();    /* clean up memory allocation & temp files */
  180.   }
  181.   exit(EXIT_FAILURE);
  182. }
  183.  
  184. #endif
  185.  
  186.  
  187. /*
  188.  * Optional routine to display a percent-done figure on stderr.
  189.  * See jcdeflts.c for explanation of the information used.
  190.  */
  191.  
  192. #ifdef PROGRESS_REPORT
  193.  
  194. METHODDEF void
  195. progress_monitor (compress_info_ptr cinfo, long loopcounter, long looplimit)
  196. {
  197.   if (cinfo->total_passes > 1) {
  198.     fprintf(stderr, "\rPass %d/%d: %3d%% ",
  199.         cinfo->completed_passes+1, cinfo->total_passes,
  200.         (int) (loopcounter*100L/looplimit));
  201.   } else {
  202.     fprintf(stderr, "\r %3d%% ",
  203.         (int) (loopcounter*100L/looplimit));
  204.   }
  205.   fflush(stderr);
  206. }
  207.  
  208. #endif
  209.  
  210.  
  211. /*
  212.  * Argument-parsing code.
  213.  * The switch parser is designed to be useful with DOS-style command line
  214.  * syntax, ie, intermixed switches and file names, where only the switches
  215.  * to the left of a given file name affect processing of that file.
  216.  * The main program in this file doesn't actually use this capability...
  217.  */
  218.  
  219.  
  220. static char * progname;        /* program name for error messages */
  221.  
  222.  
  223. LOCAL void
  224. usage (void)
  225. /* complain about bad command line */
  226. {
  227.   fprintf(stderr, "usage: %s [switches] ", progname);
  228. #ifdef TWO_FILE_COMMANDLINE
  229.   fprintf(stderr, "inputfile outputfile\n");
  230. #else
  231.   fprintf(stderr, "[inputfile]\n");
  232. #endif
  233.  
  234.   fprintf(stderr, "Switches (names may be abbreviated):\n");
  235.   fprintf(stderr, "  -quality N     Compression quality (0..100; 5-95 is useful range)\n");
  236.   fprintf(stderr, "  -grayscale     Create monochrome JPEG file\n");
  237. #ifdef ENTROPY_OPT_SUPPORTED
  238.   fprintf(stderr, "  -optimize      Optimize Huffman table (smaller file, but slow compression)\n");
  239. #endif
  240. #ifdef TARGA_SUPPORTED
  241.   fprintf(stderr, "  -targa         Input file is Targa format (usually not needed)\n");
  242. #endif
  243.   fprintf(stderr, "Switches for advanced users:\n");
  244.   fprintf(stderr, "  -restart N     Set restart interval in rows, or in blocks with B\n");
  245. #ifdef INPUT_SMOOTHING_SUPPORTED
  246.   fprintf(stderr, "  -smooth N      Smooth dithered input (N=1..100 is strength)\n");
  247. #endif
  248.   fprintf(stderr, "  -maxmemory N   Maximum memory to use (in kbytes)\n");
  249.   fprintf(stderr, "  -verbose  or  -debug   Emit debug output\n");
  250.   fprintf(stderr, "Switches for wizards:\n");
  251. #ifdef C_ARITH_CODING_SUPPORTED
  252.   fprintf(stderr, "  -arithmetic    Use arithmetic coding\n");
  253. #endif
  254. #ifdef C_MULTISCAN_FILES_SUPPORTED
  255.   fprintf(stderr, "  -nointerleave  Create noninterleaved JPEG file\n");
  256. #endif
  257.   fprintf(stderr, "  -qtables file  Use quantization tables given in file\n");
  258.   fprintf(stderr, "  -sample HxV[,...]  Set JPEG s